/**
 * 此脚本代表一个世界
 * 这个世界的地图配置
 * 世界名称
 *  产出哪些怪物  等级范围  生成任务id
 * 格子管理
 */

import app from "../../app";
import { template } from "../../shared/master/MsgAction";
import { baseCalss } from "../base/baseCalss";
import { player } from "../fight/body/player";
import { logger } from "../server/logger";
import cell from "./cell";
import manage_word from "../../master/model/manage/manage_word";
import { wordBoss } from "./wordBoss";
import { wordTask, wordTaskCfg } from "../../master/model/task/wordTask";
import { npc } from "../fight/body/npc";
export interface wordCfg {
    /**
     * 世界id
     */
    id: string,
    name: string,
    width: number;
    height: number
    // 推荐等级
    fallScoreMin: number
    fallScoreMax: number
    fallDownRang:number
    enemyTable: string
    baseExp: number

    /**
     * 世界 boss 表
     */
    bossTable: string
    wordDesc: string
    pvp: number
    /**
     * 是否禁止钓鱼
     */
    fishing: number
    /**
     * 是否禁止砍树
     */
    chopping: number
    /**
     * 是否为迷宫
     */
    maze: number
    /**
     * 宝箱概率
     */
    giftBox: number
}
export default class word extends baseCalss {
    id: string = '0'
    name: string = '位置空间';
    cellGroup: Map<string, cell> = new Map();
    cfg: wordCfg;
    _enemyMap: Map<string, any> = new Map();
    bossCls!: wordBoss;
    stayPlayer: Map<string, player> = new Map();
    private pvp: boolean = false;
    constructor(cfg: wordCfg) {
        super();
        this.id = cfg.id;
        this.name = cfg.name;
        this.cfg = Object.assign({}, cfg);
        this.cfg.name = '哈哈哈哈';
        this._enemyMap = app.xlsxCfgMap.get(cfg.enemyTable) as Map<any, any> || new Map();
        this.initMap(cfg.width, cfg.height)

        this.bossCls = new wordBoss(app.xlsxCfgMap.get(cfg.bossTable), this);

        this.pvp = !!cfg.pvp
    }
    getAverageleve() {
        let allLeve = 0;
        this.stayPlayer.forEach((e) => {
            allLeve += e.leve.num
        })
        return allLeve / this.stayPlayer.size
    }
    /**
     * 设置全部格子PVP状态
     */
    tool_setPVP(b: boolean) {
        this.pvp = b;
        // this.cellGroup.forEach(element => {
        //     element?.setPVP(b)
        // });
    }
    tool_lockEnemy(id: string) {
        // this.enemyUnLockMap.delete(id)
    }
    /**
  * 解锁指定怪物
  */
    tool_unlockEnemy(id: string) {
        // if (!this._enemyMap.has(id)) {
        //     console.error(`怪物解锁 - 没有找到ID为${id}的怪物`)
        //     return;
        // }
        // this.enemyUnLockMap.set(id, this._enemyMap.get(id))
    }
    wordCallMsg(tel: template, data?) {
        this.stayPlayer.forEach(element => {
            element.sendMsg(tel, data)
        });
    }
    outPlayer(body: player) {
        this.stayPlayer.delete(body.uuid);
        if (this.stayPlayer.size == 0) {
            // 销毁世界
            this.closeWord()
        }
        logger.debug(`离开世界 - ${this.name} -${body.name}`)
    }
    private closeWord() {
        if (this.id == '1') {
            return;
        }
        manage_word.offWord(this.id)
    }
    // 销毁世界
    destroy() {
        this.cellGroup.forEach((e) => {
            e?.destroy()
        })
        this.bossCls.destroy();
        super.destroy();
    }
    async joinPlayer(body: player) {
        if (this.stayPlayer.has(body.uuid)) {
            debugger;
            return;
        }
        return new Promise((resolve, reject) => {
            logger.debug(`进入世界 - ${this.name} -${body.name}`)
            this.stayPlayer.set(body.uuid, body)
            setTimeout(() => {
                let _cell = this.getSalfCell();
                body.setPosition(_cell);
                /**
    * 创建分配世界任务
    */
                if (this.id == '1' || this.id == 'EndlessCorridor' || this.id == 'mingame') {
                    body.setWordTask(undefined);
                } else {
                    this.randomWordTask(body);
                }
                resolve(true)
            }, 100)
        })


    }
    randomWordTask(active: player) {
        let task: wordTaskCfg = {
            v: 100,
            taskGold: app.random(900, 1200),
            wordLeve: app.random(active.leve.num, active.leve.num * 2)
        }
        let cls = new wordTask(task, active);
        active.setWordTask(cls);
        return cls;
    }
    getCell(x: number, y: number) {
        if (!this.cellGroup.has(`${x}_${y}`)) {
            return undefined
        }
        let _cell = this.cellGroup.get(`${x}_${y}`)
        if (!_cell) {
            _cell = new cell(x, y);
            _cell.setWord(this)
            _cell.setPVP(this.pvp)
            this.cellGroup.set(`${x}_${y}`, _cell);
        }
        return _cell;
    }
    private async initMap(width: number, height: number) {

        const maze = Array.from({ length: height }, () =>
            Array.from({ length: width }, () => 0)
        );
        if (this.cfg.maze) {
            const directions = [
                [-1, 0], // 上
                [0, 1],  // 右
                [1, 0],  // 下
                [0, -1]  // 左
            ];
            const isValid = (x, y) => {
                return x >= 0 && x < height && y >= 0 && y < width && maze[x][y] === 0;
            };
            const carvePath = (startX, startY) => {
                const stack = [[startX, startY]];

                while (stack.length > 0) {
                    const [x, y] = stack.pop() as number[];
                    maze[x][y] = 1;

                    const dirs = directions.slice(); // 避免重复创建数组
                    app.shuffleArray(dirs)

                    for (const [dx, dy] of dirs) {
                        const nx = x + (dx << 1); // 使用位运算代替乘法
                        const ny = y + (dy << 1);

                        if (isValid(nx, ny)) {
                            maze[x + dx][y + dy] = 1;
                            maze[nx][ny] = 1;
                            stack.push([nx, ny]);

                            // let __cell = new cell(x + dx, y + dy);
                            // __cell.setWord(this)
                            this.cellGroup.set(`${x + dx}_${y + dy}`, undefined as unknown as cell)

                            // let __cell2 = new cell(nx, ny);
                            // __cell2.setWord(this)
                            this.cellGroup.set(`${nx}_${ny}`, undefined as unknown as cell)
                        }
                    }
                }
            };
            carvePath(0, 0);
        } else {

            let preMap = app.xlsxCfgMap.get(`pre_${this.id}`) || new Map()
            for (let i = 0; i < width; i++) {
                for (let j = 0; j < height; j++) {
                    let item = preMap.get(`${i}_${j}`)
                    if (item) {
                        let __cell = new cell(i, j);
                        __cell.setWord(this)
                        let npcCfg = new Map();
                        npcCfg.set('1', item)
                        let _npc = app.createUnity('1', 100000, npcCfg, 100000, 3);
                        __cell.add(_npc)

                        this.cellGroup.set(`${i}_${j}`, __cell)
                    } else {
                        this.cellGroup.set(`${i}_${j}`, undefined as unknown as cell)
                    }
                }
            }
        }




    }
    /**
     * 获取一个安全的格子
     * 安全定义 
     * - 可移动
     */
    getSalfCell() {
        const valuesArray = Array.from(this.cellGroup.keys());
        // 随机选择一个索引
        const randomIndex = Math.floor(Math.random() * valuesArray.length);
        // 使用随机索引从数组中获取一个值
        const randomValue = valuesArray[randomIndex];
        const arry = randomValue.split('_')
        return this.getCell(Number(arry[0]), Number(arry[1])) as cell
    }
}